#ifndef __PROTOCOL_GPP__
#define __PROTOCOL_GPP__

#include <iostream>
#include <string>

const std::string spacesep = " ";
const std::string linefeedsep = "\n";

// 封装报头
//"7"\n"10 + 10"\n   这里进行编码就不用两个参数了
bool Encode(const std::string &pakeage, std::string *content)
{
    int len = pakeage.size();
    std::string tmp;
    tmp += std::to_string(len);
    tmp += linefeedsep;
    tmp += pakeage;
    tmp += linefeedsep;

    *content = tmp;

    return true;
}

// 去报头
//"7"\n"10 + 10"\n   这个你没有包含最后的\n吗，就是7的长度，我刚刚数了下，没有包含
bool Decode(std::string &package, std::string* content)
{
    int pos = package.find(linefeedsep);
    if (pos == std::string::npos)
        return false;
    std::string len_str = package.substr(0, pos);
    int len = stoi(len_str);
    int len_total = len + pos + 2;
    if (len_total < package.size())
        return false;
    std::string contentval = package.substr(pos + 1, len);

    *content = contentval;
    package.erase(0, len_total);

    return true;
}

// 请求类
class Request
{
public:
    Request()
    {
    }

    Request(int _x, int _y, char _op) : x(_x), y(_y), op(_op)
    {
    }
    //"10 + 10"
    // 序列化
    bool serialize(std::string *out)
    {
        *out += std::to_string(x);
        *out += spacesep;
        *out += op;
        *out += spacesep;
        *out += std::to_string(y);

        return true;
    }

    // x = 10 y = 10 op = +
    // 反序列化
    bool Deserialize(const std::string &in)
    {
        //"10 + 10"
        int left = in.find(spacesep);
        if (left == std::string::npos)
            return false;
        std::string part_x = in.substr(0, left);
        int right = in.rfind(spacesep);
        if (right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right)
            return false;

        op = in[left + 1];
        x = stoi(part_x);
        y = stoi(part_y);

        return true;
    }

    void Print()
    {
        std::cout << x << ' ' << op << ' ' << y << std::endl;
    }

public:
    int x;
    int y;
    char op;
};

// 响应类
class Response
{
public:
    Response()
    {
    }
    Response(int _result, int _code) : result(_result), code(_code)
    {
    }
    //"result code"
    // 序列化
    bool serialize(std::string *out)
    {
        *out += std::to_string(result);
        *out += spacesep;
        *out += std::to_string(code);

        return true;
    }

    // result = 10 code = 0
    // 反序列化
    bool Deserialize(const std::string &in)
    {
        //"10 0"
        int left = in.find(spacesep);
        if (left == std::string::npos)
            return false;
        std::string part_result = in.substr(0, left);
        int right = in.rfind(spacesep);
        if (right == std::string::npos)
            return false;
        std::string part_code = in.substr(right + 1);

        if (left != right)
            return false;

        result = stoi(part_result);
        code = stoi(part_code);

        return true;
    }

    void Print()
    {
        std::cout << "result: " << result << " code: " << " " << code << std::endl;
    }

public:
    int result;
    int code;
};

#endif